package com.bluemsun.naturallanguageprocessing.service.impl;


import com.bluemsun.naturallanguageprocessing.common.ServerResponse;
import com.bluemsun.naturallanguageprocessing.dao.*;
import com.bluemsun.naturallanguageprocessing.entity.Question;
import com.bluemsun.naturallanguageprocessing.entity.UserApi;
import com.bluemsun.naturallanguageprocessing.service.IRecommendService;
import com.bluemsun.naturallanguageprocessing.util.ConductRedisUtil;
import com.bluemsun.naturallanguageprocessing.vo.*;
import org.slf4j.Logger;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author ：hj
 * @date ：Created in 2021/4/12 11:57
 * @description：推荐
 * @modified By：
 * @version: $
 */
@Service("IRecommendService")
public class IRecommendServiceImpl implements IRecommendService {

    private static final Logger logger =  LoggerFactory.getLogger(com.bluemsun.naturallanguageprocessing.service.impl.IRecommendServiceImpl.class);;

    @Autowired
    CorMapper corMapper;
    @Autowired
    ConductRedisUtil conductRedisUtil;
    @Autowired
    BrowseMapper browseMapper;
    @Autowired
    UserTagMapper userTagMapper;
    @Autowired
    QuestionMapper questionMapper;
    @Autowired
    TagMapper tagMapper;
    @Autowired
    UserMapper userMapper;

    List<QuestionVO> read(String fileName)  {
        List<QuestionVO> list = new ArrayList<QuestionVO>();
        try {
            FileInputStream fis = new FileInputStream(fileName);
            InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
            BufferedReader br = new BufferedReader(isr);

            String line = "";
            while ((line = br.readLine()) != null) {
                QuestionVO questionVO = new QuestionVO();
                String[] line1 = line.split(" ");
                questionVO.setId(Integer.parseInt(line1[0]));
                questionVO.setTitle(line1[1]);
                list.add(questionVO);
            }
            br.close();
            isr.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
            logger.error("Ioexception",e);
        }
        return list;
    }
    void jaccard1(List<QuestionVO> list) {
        CorVO corVO;
        List<CorVO> list1 = new ArrayList<CorVO>();
        for (QuestionVO str1 : list) {
            for (QuestionVO str2 : list) {
                corVO = new CorVO();
                Set<Character> s1 = new HashSet<>();//set元素不可重复
                Set<Character> s2 = new HashSet<>();
                if (str1.equals(str2)) {
                    continue;
                }
                for (int i = 0; i < str1.getTitle().length(); i++) {
                    s1.add(str1.getTitle().charAt(i));//将string里面的元素一个一个按索引放进set集合
                }
                for (int j = 0; j < str2.getTitle().length(); j++) {
                    s2.add(str2.getTitle().charAt(j));
                }

                float mergeNum = 0;//并集元素个数
                float commonNum = 0;//相同元素个数（交集）

                for (Character ch1 : s1) {
                    for (Character ch2 : s2) {
                        if (ch1.equals(ch2)) {
                            commonNum++;
                        }
                    }
                }

                mergeNum = s1.size() + s2.size() - commonNum;

                float jaccard = commonNum / mergeNum;
                corVO.setBaseTitle(str1.getId());
                corVO.setSimTitle(str2.getId());
                corVO.setCorr(jaccard);
                list1.add(corVO);
            }
        }
        corMapper.insertSelective(list1);
    }

    public ServerResponse CalculateCorr() {
        String filesname = "src/main/resources/data/keywords";
        File file = new File(filesname);

        File[] files = file.listFiles();

        for (int i = 0; i < files.length; i++) {
            List<QuestionVO> list = read(files[i].getPath());
            jaccard1(list);
        }
        return ServerResponse.createBySuccess();
    }

    @Override
    public ServerResponse recommend(HttpServletRequest request,Integer pageSize,Integer pageNum) {
        UserApi userApi = conductRedisUtil.getUserFromRedis(request.getHeader("token"));
        UserApi userApi1 = userMapper.Select(userApi.getId());
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long startDateTime = 0;
        long endDateTime = 0;
        try {
            startDateTime = dateFormat.parse(dateFormat.format(userApi1.getUpdateTime())).getTime();
            endDateTime = dateFormat.parse(dateFormat.format(date)).getTime();
        } catch (ParseException e) {
            logger.error("时间转换出错", e);
            e.printStackTrace();
        }
        //修改时间在一天以外
        if (endDateTime - startDateTime > 1000 * 3600 * 24) {
            List<BrowseVO> list = browseMapper.getBrowse(userApi.getId(), 1, 20);
            //该用户没有浏览记录

            if (list == null || list.size() == 0) {
                List<UserTagVO> list1 = userTagMapper.getUserSelect(userApi.getId());
                //该用户没有选择喜好标签
                if (list1 == null || list1.size() == 0) {
                    PageVO<Question> pageVo = new PageVO(pageNum, pageSize, questionMapper.count());
                    pageVo.setList(questionMapper.selectQuestionByPage(pageVo.getStartIndex(), pageSize));
                    return ServerResponse.createBySuccess("返回热度", pageVo);
                }
                //根据用户标签分页
                List<TagVO> list2 = new ArrayList<>();
                list2 = userTagMapper.getTag(list1);
                PageVO<Question> pageVO = new PageVO(pageNum, pageSize, tagMapper.count(list2));
                pageVO.setList(questionMapper.selectQuestionByUserTag(list2, pageVO.getStartIndex(), pageSize));
                return ServerResponse.createBySuccess("返回根据标签推荐", pageVO);
            }
            //根据相识度返回

            PageVO<Question> pageVO1 = new PageVO<>(pageNum, pageSize, corMapper.countQuestionByCorr(list));
            List list3 = questionMapper.selectQuestionByCorr(list, pageVO1.getStartIndex(), pageSize);
            if (list3.size() == 0) {
                List<UserTagVO> list1 = userTagMapper.getUserSelect(userApi.getId());
                //该用户没有选择喜好标签
                if (list1 == null || list1.size() == 0) {
                    PageVO<Question> pageVo = new PageVO(pageNum, pageSize, questionMapper.count());
                    pageVo.setList(questionMapper.selectQuestionByPage(pageVo.getStartIndex(), pageSize));
                    return ServerResponse.createBySuccess("返回热度", pageVo);
                }
                //根据用户标签分页
                List<TagVO> list2 = new ArrayList<>();
                list2 = userTagMapper.getTag(list1);
                PageVO<Question> pageVO = new PageVO(pageNum, pageSize, tagMapper.count(list2));
                pageVO.setList(questionMapper.selectQuestionByUserTag(list2, pageVO.getStartIndex(), pageSize));
                return ServerResponse.createBySuccess("返回根据标签推荐", pageVO);
            } else {
                pageVO1.setList(list3);
            }
            return ServerResponse.createBySuccess("返回根据相识度推荐", pageVO1);
        }
        //
        else {
            List<UserTagVO> list1 = userTagMapper.getUserSelect(userApi.getId());
            //该用户没有选择喜好标签
            if (list1 == null || list1.size() == 0) {
                PageVO<Question> pageVo = new PageVO(pageNum, pageSize, questionMapper.count());
                pageVo.setList(questionMapper.selectQuestionByPage(pageVo.getStartIndex(), pageSize));
                return ServerResponse.createBySuccess("返回热度", pageVo);
            }
            //根据用户标签分页
            List<TagVO> list2 = new ArrayList<>();
            list2 = userTagMapper.getTag(list1);
            PageVO<Question> pageVO = new PageVO(pageNum, pageSize, tagMapper.count(list2));
            pageVO.setList(questionMapper.selectQuestionByUserTag(list2, pageVO.getStartIndex(), pageSize));
            return ServerResponse.createBySuccess("返回根据标签推荐", pageVO);
        }
    }
}
